Skip to content

size-bound 50 MB packs by default, fix stale chunk index after compact pack rewrites - #9852

Merged
ThomasWaldmann merged 3 commits into
borgbackup:masterfrom
mr-raj12:pack-defaults-compact-index-fix
Jul 3, 2026
Merged

size-bound 50 MB packs by default, fix stale chunk index after compact pack rewrites#9852
ThomasWaldmann merged 3 commits into
borgbackup:masterfrom
mr-raj12:pack-defaults-compact-index-fix

Conversation

@mr-raj12

@mr-raj12 mr-raj12 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Description

Two changes, one commit each.

Pack sizing defaults (fixes #9843)

Packs are now bound by size: max_size=50_000_000, max_count=None. The old max_count=3 was a testing value. The testsuite sets BORG_PACK_MAX_COUNT=3 via the clean_env fixture, so small test data still produces multiple multi-object packs and the rollover and compaction code paths stay covered.

compact left a stale chunk index after pack rewrites (fixes #9850)

I traced the ObjectNotFound crash from #9850 to this: borg compact computes its keep/drop sets from its own chunk index, but compact_pack() applied the resulting updates to repository.chunks, a different index object. save_chunk_index() then persisted the unchanged index, so after every mixed-pack rewrite the persisted entries still pointed at the deleted old pack. Once a later borg delete made all of that phantom pack's entries unused, the next compact classified it as droppable and crashed trying to delete a pack file that was already gone.

No data is lost in this situation: the kept objects were copied into the new pack, only the persisted pointers were stale. Rebuilding the index from the packs (deleting the index/* objects) repairs an affected repository.

Fixes:

  • compact_pack() takes a chunks parameter and compact passes the index it computed keep/drop from, so the updates land in the index that gets persisted. As a side effect this removes a full slow index rebuild that happened mid-compact, when compact_pack() lazily rebuilt repository.chunks after the cached indexes had been invalidated.
  • Deleting a pack that is already gone logs a warning instead of crashing. A repository with a stale index then self-heals: compact removes the stale entries and writes a fresh index.
  • get_repository_chunks() passes init_flags=F_NONE (found while reading the code: without it, a compact run that has to rebuild the index from the packs marks everything used and frees nothing).

Both bugs have regression tests that fail on master: one drives create/delete/compact through a mixed pack rewrite and checks that the persisted index only references existing packs, that extract still works and that a second delete + compact completes; the other covers garbage collection after the cached index was lost.

Checklist

  • PR is against master (or maintenance branch if only applicable there)
  • New code has tests and docs where appropriate
  • Tests pass (run tox or the relevant test subset)
  • Commit messages are clean and reference related issues

mr-raj12 added 2 commits July 3, 2026 16:52
max_count=3 was a testing value. The default is now max_count=None,
max_size=50_000_000; the testsuite sets BORG_PACK_MAX_COUNT=3 instead,
so small test data still produces multiple multi-object packs.
…orgbackup#9850

compact_pack() updated repository.chunks, but compact computes keep/drop from
and persists its own index, which kept pointing at the deleted packs. Also:
tolerate deleting already-gone packs, start rebuilt index entries as unused.
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.94737% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.11%. Comparing base (3969aea) to head (a8c2c7b).
⚠️ Report is 22 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/borg/archiver/compact_cmd.py 71.42% 2 Missing ⚠️
src/borg/repository.py 80.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #9852   +/-   ##
=======================================
  Coverage   85.11%   85.11%           
=======================================
  Files          93       93           
  Lines       15388    15409   +21     
  Branches     2322     2326    +4     
=======================================
+ Hits        13097    13115   +18     
- Misses       1592     1596    +4     
+ Partials      699      698    -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@ThomasWaldmann ThomasWaldmann left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good you found that bug!

some nitpicks.

Comment thread src/borg/repository.py Outdated
Comment thread src/borg/repository.py Outdated

@ThomasWaldmann ThomasWaldmann left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@ThomasWaldmann
ThomasWaldmann merged commit 98bf113 into borgbackup:master Jul 3, 2026
18 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

borg2: crash while compact adjust max_size / max_count before beta release

2 participants